package com.sms.plateform.kernel.service.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sms.plateform.common.finals.Constants;
import com.sms.plateform.common.util.DateUtil;
import com.sms.plateform.common.util.ExistsValidator;
import com.sms.plateform.common.util.SequenceGenerator;
import com.sms.plateform.common.util.Utils;
import com.sms.plateform.kernel.dao.IRaskApplyDao;
import com.sms.plateform.kernel.entity.ChannelInfo;
import com.sms.plateform.kernel.entity.PriceBlotters;
import com.sms.plateform.kernel.entity.PriceInfo;
import com.sms.plateform.kernel.entity.RaskApply;
import com.sms.plateform.kernel.service.IGroupInfoService;
import com.sms.plateform.kernel.service.IMainRaskService;
import com.sms.plateform.kernel.service.IPriceBlottersService;
import com.sms.plateform.kernel.service.IPriceInfoService;
import com.sms.plateform.web.cache.ChannelCache;

@Service
public class MainRaskServiceImpl  implements IMainRaskService{
	@Autowired
	private IGroupInfoService groupInfoService;
	@Autowired
	private ChannelCache channelCache;
	@Autowired
	private IRaskApplyDao raskApplyDao;
	@Autowired
	private IPriceBlottersService priceBlottersService;
	@Autowired
	private IPriceInfoService priceInfoService;
	@Autowired
	private DataSource dataSource;
	/**
	 * 批次发送入口
	 */
	public int sendBatchMessage(String username,String password,String mobiles,String contents){
		//可在执行时加锁
		//生成本次发送的批次号
		String batchID=DateUtil.getBatchID()+Constants.PLATEFORM_SDK;//生成批次号码
		//判断用户名
		if(Utils.trim(username).length()<1){
			return Constants.STATUS_106;
		}
		//判断密码
		if(Utils.trim(password).length()<1){
			return Constants.STATUS_106;
		}
		//判断手机号
		if(Utils.trim(mobiles).length()<1){
			return Constants.STATUS_106;
		}
		//判断内容
		if(Utils.trim(contents).length()<1){
			return Constants.STATUS_106;
		}
		//内容关键子检查
		if (Utils.includeFilterWord(contents)) {
			return Constants.STATUS_104;
		}
		//关键号码检查
		if (Utils.includeFilterWord(mobiles)) {
			return Constants.STATUS_107;
		}
		// 号码集合
		List<String> mob_arrs = new ArrayList<String>();
		// 号码分批
		HashMap<Integer, ArrayList<String>> mtypes = new HashMap<Integer, ArrayList<String>>(3);
		// new 一个新的号码字符串
		StringBuilder newMobilesSb = new StringBuilder();
		// new 一个错误号码字符串
		StringBuilder errorMobilesSb = new StringBuilder();
		String[] arrs = mobiles.split(",");
		for (int i = 0; i < arrs.length; i++) {
			String element = arrs[i];
			// 判断是否为手机号码
			if (ExistsValidator.IsPhone(element)) {
				newMobilesSb.append(",").append(element);
				mob_arrs.add(element);
				Integer mtype = ExistsValidator.findMobileType(element);// 检查该号码属于移动还是联通还是其他
				if (mtypes.get(mtype) == null) {
					ArrayList<String> ms = new ArrayList<String>();
					ms.add(element);
					mtypes.put(mtype, ms);
				} else {
					mtypes.get(mtype).add(element);
				}
			} else {
				errorMobilesSb.append("," + element);
				continue;
			}
		}
		//判断是否有错误号码
		if (errorMobilesSb.length() > 0) {
			return Constants.STATUS_107;
		}
		if(mob_arrs.size()<1){
			return Constants.STATUS_106;
		}
		//号码数量
		int mobile_num=mob_arrs.size();
		if(mobile_num>Constants.PACK_NUM){
			return Constants.STATUS_108;
		}
		Map<String, Object> param=new HashMap<String, Object>();
		param.put("username", username);
		param.put("password", password);
		HashMap<String, Object> hashMap=this.groupInfoService.getUserGroupPriceInfo(param);
		System.out.println(hashMap);
		//判断用户是否存在
		if(hashMap==null || !Utils.trim(hashMap.get("username")).equals(username)){
			return Constants.STATUS_105;
		}else{
			int status=Integer.parseInt(Utils.trim(hashMap.get("status")));
			//判断用户状态
			if(Constants.USER_STATUS_002==status||Constants.USER_STATUS_003==status){
				//用户余额
				int balance=Integer.parseInt(Utils.trim(hashMap.get("balance")));
				if(balance<1){
					return Constants.STATUS_116;
				}
				//获取用户通道对应网关信息
				String channel=Utils.trim(hashMap.get("channel"));
				String channelIds[] =channel.split(",");
				if (channelIds.length < 3) {
					return Constants.STATUS_106;
				}else{
					//获取通道信息
					Map<String, ChannelInfo> channelInfoMap=this.channelCache.getChannelInfoMap();
					ChannelInfo ydChannelInfo=channelInfoMap.get(channelIds[0]);
					ChannelInfo ltChannelInfo=channelInfoMap.get(channelIds[1]);
					ChannelInfo dxChannelInfo=channelInfoMap.get(channelIds[2]);
					//定义大批次的发送总条数
					int send_num_count=0;
					//获取连接,重新手动定义事物操作
					Connection conn=null;
					PreparedStatement pstmt=null;
					try {
						int gid=Integer.parseInt(Utils.trim(hashMap.get("gid")));
						int stype=1;
						int feetype=1;
						int priority=Integer.parseInt(Utils.trim(hashMap.get("priority")));
						int isaudit=Integer.parseInt(Utils.trim(hashMap.get("isaudit")));
						int issend=Integer.parseInt(Utils.trim(hashMap.get("issend")));
						int pid=Integer.parseInt(Utils.trim(hashMap.get("pid")));
						conn=dataSource.getConnection();
						conn.setAutoCommit(false);
						System.out.println(conn);
						String sql_rask_query="insert into rask_query(gid,batchid,batchsubid,stype,feetype,channelid,mobile,message,mobile_num,message_num,priority,isaudit,issend,status,error,sendtime,updatetime)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
						pstmt=conn.prepareStatement(sql_rask_query);
						//开始处理号码数据
						Iterator<Entry<Integer, ArrayList<String>>> iter = mtypes.entrySet().iterator();
						while (iter.hasNext()) {
							Entry<Integer, ArrayList<String>> entry = iter.next();
							Integer mtype = entry.getKey();
							if (mtype < 1 || mtype > 3)
								continue;
							int channelId = 0;
							int con_size=Constants.CHAR_SIZE;
							int pack_num=Constants.PACK_NUM;
							if (mtype == 1){
								channelId = ydChannelInfo.getId();
								con_size=ydChannelInfo.getMaxmsg();
								pack_num=ydChannelInfo.getMaxnum();
							}else if (mtype == 2){
								channelId = ltChannelInfo.getId();
								con_size=ltChannelInfo.getMaxmsg();
								pack_num=ltChannelInfo.getMaxnum();
							}else if (mtype == 3){
								channelId = dxChannelInfo.getId();
								con_size=dxChannelInfo.getMaxmsg();
								pack_num=dxChannelInfo.getMaxnum();
							}else{
								channelId = ydChannelInfo.getId();
								con_size=ydChannelInfo.getMaxmsg();
								pack_num=ydChannelInfo.getMaxnum();
							}
							//要处理的手机号码集合
							ArrayList<String> mbs = entry.getValue();
							//获取号码数量
							int mob_size=mbs.size();
							//发送内容
							String newcontents=Utils.trim(contents);
							//发送条数
							int con_num=(int) Math.ceil(newcontents.length() * 1.0 / con_size);
							//发送量
							int send_num=con_num * mob_size;
							//获所有批次的总数
							send_num_count=send_num_count+send_num;
							//开始处理网关设置的发送数量
							StringBuilder sb = new StringBuilder();
							for (int i = 0; i < mbs.size(); i++) {
								String mb = mbs.get(i);
								sb.append(",").append(mb);
								if ((i + 1) % pack_num == 0 || i == mbs.size() - 1) {
									int packn = 0; //根据算法计算出号码的数量和要发送的号码
									if ((i + 1) % pack_num == 0) {
										packn = pack_num;
									} else {
										packn = (i + 1) % pack_num;
									}
									//处理SQL语句
									pstmt.setInt(1, gid);
									pstmt.setString(2, batchID);
									pstmt.setString(3, SequenceGenerator.nextSequence()+"");
									pstmt.setInt(4, stype);
									pstmt.setInt(5, feetype);
									pstmt.setInt(6, channelId);
									pstmt.setString(7, sb.substring(1));
									pstmt.setString(8, newcontents);
									pstmt.setInt(9, packn);
									pstmt.setInt(10, con_num);
									pstmt.setInt(11, priority);
									pstmt.setInt(12, isaudit);
									pstmt.setInt(13, issend);
									pstmt.setInt(14, 1);
									pstmt.setInt(15, 0);
									pstmt.setString(16, null);
									pstmt.setString(17, DateUtil.getCurrentDateTime());
									pstmt.addBatch();
									sb.setLength(0);
								} 
							}
						}
						//判断要发送的数量
						if(balance<send_num_count){
							return Constants.STATUS_116;
						}
						//执行提交
						int st[]=pstmt.executeBatch();
						conn.commit();
						//记录总任务 记录发送类型、计费类型、发送总数量
						RaskApply raskApply=new RaskApply();
						raskApply.setBatchid(batchID);
						raskApply.setGid(gid);
						raskApply.setStype(stype);
						raskApply.setFeetype(feetype);
						raskApply.setRate(Double.parseDouble("0"));
						raskApply.setSendcount(send_num_count);
						raskApplyDao.insert(raskApply);
						//记录流水张
						PriceBlotters priceBlotters=new PriceBlotters();
						priceBlotters.setBatchid(batchID);
						priceBlotters.setPriceid(pid);
						priceBlotters.setBalance(balance);
						priceBlotters.setSpend(-send_num_count);
						priceBlotters.setRemark("");
						priceBlottersService.insert(priceBlotters);
						//修改账户余额
						PriceInfo priceInfo=new PriceInfo();
						priceInfo.setId(pid);
						priceInfo.setGid(gid);
						priceInfo.setBalance(balance-send_num_count);
						priceInfoService.update(priceInfo);
					    if(st!=null && st.length>0){
					    	return Constants.STATUS_111;
					    }
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						try {
							conn.rollback();
						} catch (SQLException e1) {}
						return Constants.STATUS_110;
					}finally{
						try {
							conn.close();
						} catch (SQLException e) {}
					}
				}
			}else{
				return Constants.STATUS_115;
			}
		}
		return Constants.STATUS_100;
	}
	public int sendBatchMessage(int uid, int stype, String sendtime,int priority, String mobiles, String contents) {
		// TODO Auto-generated method stub
		//可在执行时加锁
		//生成本次发送的批次号
		String batchID=DateUtil.getBatchID()+Constants.PLATEFORM_WEB;//生成批次号码
		//判断是否定时
		int send_status=1;
		sendtime=sendtime==""?null:sendtime;
		if(Constants.STYPE_002==stype){
			if(Utils.trim(sendtime)==null){
				return Constants.STATUS_106;
			}
			//判断时间是否大于当前时间并且小于半年
			Date date_time = DateUtil.getDate(sendtime, "yyyy-MM-dd HH:mm");
			if (new Date().after(date_time)) {
				return Constants.STATUS_117;
			}else{
				send_status=3;//设置3定时状态
			}
		}
		//判断手机号
		if(Utils.trim(mobiles).length()<1){
			return Constants.STATUS_106;
		}
		//判断内容
		if(Utils.trim(contents).length()<1){
			return Constants.STATUS_106;
		}
		//判断内容长度
//		if(Utils.trim(contents).length()>Constants.CHAR_SIZE){
//			return Constants.STATUS_109;
//		}
		//内容关键子检查
		if (Utils.includeFilterWord(contents)) {
			return Constants.STATUS_104;
		}
		//关键号码检查
		if (Utils.includeFilterWord(mobiles)) {
			return Constants.STATUS_107;
		}
		// 号码集合
		List<String> mob_arrs = new ArrayList<String>();
		// 号码分批
		HashMap<Integer, ArrayList<String>> mtypes = new HashMap<Integer, ArrayList<String>>(3);
		// new 一个新的号码字符串
		StringBuilder newMobilesSb = new StringBuilder();
		// new 一个错误号码字符串
		StringBuilder errorMobilesSb = new StringBuilder();
		String[] arrs = mobiles.split(",");
		for (int i = 0; i < arrs.length; i++) {
			String element = arrs[i];
			// 判断是否为手机号码
			if (ExistsValidator.IsPhone(element)) {
				newMobilesSb.append(",").append(element);
				mob_arrs.add(element);
				Integer mtype = ExistsValidator.findMobileType(element);// 检查该号码属于移动还是联通还是其他
				if (mtypes.get(mtype) == null) {
					ArrayList<String> ms = new ArrayList<String>();
					ms.add(element);
					mtypes.put(mtype, ms);
				} else {
					mtypes.get(mtype).add(element);
				}
			} else {
				errorMobilesSb.append("," + element);
				continue;
			}
		}
		//判断是否有错误号码
		if (errorMobilesSb.length() > 0) {
			System.out.println("有错误号码："+errorMobilesSb.toString());
			return Constants.STATUS_107;
		}
		if(mob_arrs.size()<1){
			return Constants.STATUS_106;
		}
		//号码数量
		int mobile_num=mob_arrs.size();
		if(mobile_num>Constants.PACK_NUM * 1000){
			return Constants.STATUS_108;
		}
		Map<String, Object> param=new HashMap<String, Object>();
		param.put("id", uid);
		HashMap<String, Object> hashMap=this.groupInfoService.getUserGroupPriceInfo(param);
		System.out.println(hashMap);
		//判断用户是否存在
		if(hashMap==null || uid!=Integer.parseInt(Utils.trim(hashMap.get("id")))){
			return Constants.STATUS_105;
		}else{
			int status=Integer.parseInt(Utils.trim(hashMap.get("status")));
			//判断用户状态
			if(Constants.USER_STATUS_001==status||Constants.USER_STATUS_003==status){
				//用户余额
				int balance=Integer.parseInt(Utils.trim(hashMap.get("balance")));
				if(balance<1){
					return Constants.STATUS_116;
				}
				//获取用户通道对应网关信息
				String channel=Utils.trim(hashMap.get("channel"));
				String channelIds[] =channel.split(",");
				if (channelIds.length < 3) {
					return Constants.STATUS_106;
				}else{
					//获取通道信息
					Map<String, ChannelInfo> channelInfoMap=this.channelCache.getChannelInfoMap();
					ChannelInfo ydChannelInfo=channelInfoMap.get(channelIds[0]);
					ChannelInfo ltChannelInfo=channelInfoMap.get(channelIds[1]);
					ChannelInfo dxChannelInfo=channelInfoMap.get(channelIds[2]);
					//定义大批次的发送总条数
					int send_num_count=0;
					//获取连接,重新手动定义事物操作
					Connection conn=null;
					PreparedStatement pstmt=null;
					try {
						int gid=Integer.parseInt(Utils.trim(hashMap.get("gid")));
						int feetype=1;
						int isaudit=Integer.parseInt(Utils.trim(hashMap.get("isaudit")));
						int issend=Integer.parseInt(Utils.trim(hashMap.get("issend")));
						int pid=Integer.parseInt(Utils.trim(hashMap.get("pid")));
						conn=dataSource.getConnection();
						conn.setAutoCommit(false);
						System.out.println(conn);
						String sql_rask_query="insert into rask_query(gid,batchid,batchsubid,stype,feetype,channelid,mobile,message,mobile_num,message_num,priority,isaudit,issend,status,error,sendtime,updatetime)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
						pstmt=conn.prepareStatement(sql_rask_query);
						//开始处理号码数据
						Iterator<Entry<Integer, ArrayList<String>>> iter = mtypes.entrySet().iterator();
						while (iter.hasNext()) {
							Entry<Integer, ArrayList<String>> entry = iter.next();
							Integer mtype = entry.getKey();
							if (mtype < 1 || mtype > 3)
								continue;
							int channelId = 0;
							int con_size=Constants.CHAR_SIZE;
							int pack_num=Constants.PACK_NUM;
							if (mtype == 1){
								channelId = ydChannelInfo.getId();
								con_size=ydChannelInfo.getMaxmsg();
								pack_num=ydChannelInfo.getMaxnum();
							}else if (mtype == 2){
								channelId = ltChannelInfo.getId();
								con_size=ltChannelInfo.getMaxmsg();
								pack_num=ltChannelInfo.getMaxnum();
							}else if (mtype == 3){
								channelId = dxChannelInfo.getId();
								con_size=dxChannelInfo.getMaxmsg();
								pack_num=dxChannelInfo.getMaxnum();
							}else{
								channelId = ydChannelInfo.getId();
								con_size=ydChannelInfo.getMaxmsg();
								pack_num=ydChannelInfo.getMaxnum();
							}
							//要处理的手机号码集合
							ArrayList<String> mbs = entry.getValue();
							//获取号码数量
							int mob_size=mbs.size();
							//发送内容
							String newcontents=Utils.trim(contents);
							//发送条数
							int con_num=(int) Math.ceil(newcontents.length() * 1.0 / con_size);
							//发送量
							int send_num=con_num * mob_size;
							//获所有批次的总数
							send_num_count=send_num_count+send_num;
							//开始处理网关设置的发送数量
							StringBuilder sb = new StringBuilder();
							for (int i = 0; i < mbs.size(); i++) {
								String mb = mbs.get(i);
								sb.append(",").append(mb);
								if ((i + 1) % pack_num == 0 || i == mbs.size() - 1) {
									int packn = 0; //根据算法计算出号码的数量和要发送的号码
									if ((i + 1) % pack_num == 0) {
										packn = pack_num;
									} else {
										packn = (i + 1) % pack_num;
									}
									//处理SQL语句
									pstmt.setInt(1, gid);
									pstmt.setString(2, batchID);
									pstmt.setString(3, SequenceGenerator.nextSequence()+"");
									pstmt.setInt(4, stype);
									pstmt.setInt(5, feetype);
									pstmt.setInt(6, channelId);
									pstmt.setString(7, sb.substring(1));
									pstmt.setString(8, newcontents);
									pstmt.setInt(9, packn);
									pstmt.setInt(10, con_num);
									pstmt.setInt(11, priority);
									pstmt.setInt(12, isaudit);
									pstmt.setInt(13, issend);
									pstmt.setInt(14, send_status);
									pstmt.setInt(15, 0);
									pstmt.setString(16, sendtime);
									pstmt.setString(17, DateUtil.getCurrentDateTime());
									pstmt.addBatch();
									sb.setLength(0);
								} 
							}
						}
						//判断要发送的数量
						if(balance<send_num_count){
							return Constants.STATUS_116;
						}
						//执行提交
						int st[]=pstmt.executeBatch();
						conn.commit();
						//记录总任务 记录发送类型、计费类型、发送总数量
						RaskApply raskApply=new RaskApply();
						raskApply.setBatchid(batchID);
						raskApply.setGid(gid);
						raskApply.setStype(stype);
						raskApply.setFeetype(feetype);
						raskApply.setRate(Double.parseDouble("0"));
						raskApply.setSendcount(send_num_count);
						raskApplyDao.insert(raskApply);
						//记录流水张
						PriceBlotters priceBlotters=new PriceBlotters();
						priceBlotters.setBatchid(batchID);
						priceBlotters.setPriceid(pid);
						priceBlotters.setBalance(balance);
						priceBlotters.setSpend(-send_num_count);
						priceBlotters.setRemark("");
						priceBlottersService.insert(priceBlotters);
						//修改账户余额
						PriceInfo priceInfo=new PriceInfo();
						priceInfo.setId(pid);
						priceInfo.setGid(gid);
						priceInfo.setBalance(balance-send_num_count);
						priceInfoService.update(priceInfo);
					    if(st!=null && st.length>0){
					    	return Constants.STATUS_111;
					    }
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						try {
							conn.rollback();
						} catch (SQLException e1) {}
						return Constants.STATUS_110;
					}finally{
						try {
							conn.close();
						} catch (SQLException e) {}
					}
				}
			}else{
				return Constants.STATUS_115;
			}
		}
		return Constants.STATUS_100;
	}
	
}
